

#include <arpa/inet.h>
#include <pthread.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

#include "../rocket/common/config.h"
#include "../rocket/common/log.h"
#include "../rocket/net/coder/string_coder.h"
#include "../rocket/net/coder/tinypb_coder.h"
#include "../rocket/net/coder/tinypb_protocol.h"
#include "../rocket/net/rpc/rpc_channel.h"
#include "../rocket/net/rpc/rpc_closure.h"
#include "../rocket/net/rpc/rpc_controller.h"
#include "../rocket/net/rpc/rpc_dispatcher.h"
#include "../rocket/net/tcp/tcp_client.h"
#include "order.pb.h"

// class OrderImpl : public Order {
//   public:
//     void makeOrder(google::protobuf::RpcController *controller,
//                    const ::makeOrderRequest *request,
//                    ::makeOrderResponse *response,
//                    ::google::protobuf::Closure *done) {
//         if (request->price() < 10) {
//             response->set_res_code(01);
//             response->set_res_info("short balance");
//             return;
//         }
//         response->set_order_id("123123");
//     }
// };

void test_channel() {
    NEWRPCCHANNEL(channel, "127.0.0.1:12345");

    NEWMESSAGE(makeOrderRequest, request);
    request->set_price(100);
    request->set_goods("apple");

    NEWMESSAGE(makeOrderResponse, response);

    NEWRPCCONTROLLER(controller);
    controller->SetTimeout(5000);

    auto closure_cb = [request, response, &channel, controller]() {
            if (controller->GetErrorCode() ==0) {
                INFOLOG("call rpc success, request [%s], response [%s]",
                    request->ShortDebugString().c_str(),
                    response->ShortDebugString().c_str());
                // do something after rpc success
            } else {
                ERRORLOG("call rpc failed, request[%s], error code[%d], error info[%s]", 
                    request->ShortDebugString().c_str(), controller->GetErrorCode(), controller->GetErrorInfo().c_str());
            }
            INFOLOG("exit eventloop");
            channel->getTcpClient()->stop();
            channel.reset();
        };
    NEWRPCCLOSURE(closure, closure_cb);

    CALLRPC("127.0.0.1:12345", makeOrder, controller, request, response, closure);

    // channel->Init(controller, request, response, closure);

    // Order_Stub stub(channel.get());
    // stub.makeOrder(controller.get(), request.get(), response.get(),
    //                closure.get());
}

int main() {
    rocket::Config::SetGlobalConfig("conf/rocket.xml");
    rocket::Logger::InitGlobalLogger();

    // test_tcp_client();
    test_channel();

    INFOLOG("rpc test client exit");

    return 0;
}
